import type { IRole } from '@/interfaces';
import { type ChangeEvent, useContext, useState } from 'react';
import { useMutation, useQueryClient } from '@tanstack/react-query';
import useToast, { LoginReminderContent } from '@/hooks/useToast';
import { createComment } from '@/services/api';
import sanitizeHtml from 'sanitize-html';
import type { StaticImageData } from 'next/image';
import Image from 'next/image';
import { getUserAvatar } from '@/lib/tool';
import Link from 'next/link';
import avatar from '@/public/images/avatar.png';
import { AppContext } from '@/contexts/app';
import { PostIdPageContext } from '@/contexts/post-id';
import Spinner from '@/app/[locale]/component/spinner/spinner';

export default function PostComment() {
  const {
    source: { path, postDetails },
    translatedFields,
    queryKey,
  } = useContext(PostIdPageContext)!;
  const appContext = useContext(AppContext);
  const metadata = appContext.metadata!;
  const env = metadata.env;
  const [commentContent, setCommentContent] = useState('');
  const { show } = useToast();
  const queryClient = useQueryClient();
  const [userInfo, setUserInfo] = useState<{
    id: any;
    alias: string;
    avatar: string | StaticImageData;
    roles: IRole[];
  }>(
    path.user
      ? {
          id: path.user.id,
          alias: path.user.alias,
          avatar: getUserAvatar(path.user, metadata).mediumAvatarUrl,
          roles: path.user.roles,
        }
      : {
          id: null,
          alias: translatedFields.anonymousHero,
          avatar: avatar,
          roles: [],
        },
  );

  const createCommentMutation = useMutation(createComment);

  async function onClickPostComment() {
    if (!path.user) {
      show({
        title: translatedFields.notLoggedInPrompt,
        content: <LoginReminderContent />,
      });
      return;
    }

    const _commentContent = commentContent.trim();
    if (!_commentContent) {
      show({
        type: 'DANGER',
        message: translatedFields.replyContentEmptyError,
      });
      return;
    }

    const content = sanitizeHtml(_commentContent);
    if (!content) {
      show({
        type: 'DANGER',
        message: translatedFields.replyContentEmptyError,
      });
      return;
    }

    try {
      const postId = postDetails.basic.id;
      await createCommentMutation.mutateAsync({
        data: {
          postId,
          content,
        },
      });

      await queryClient.refetchQueries(
        queryKey,
        {},
        {
          throwOnError: true,
        },
      );

      setCommentContent('');
      show({
        type: 'SUCCESS',
        message: translatedFields.replyCompleted,
      });
    } catch (e) {
      createCommentMutation.reset();
      show({
        type: 'DANGER',
        message: e,
      });
    }
  }

  function onChangeCommentContent(e: ChangeEvent<HTMLTextAreaElement>) {
    setCommentContent(e.target.value);
  }

  return (
    <div className="row mx-0">
      <div className="col-12 col-lg-2 px-0">
        <div className="card h-100 border-0 rounded-0 vstack gap-2">
          <div
            className="align-self-center my-4"
            style={{ width: 128, height: 128 }}
          >
            <Image
              className="rounded-circle card-img-top object-fit-contain"
              src={userInfo.avatar}
              alt={userInfo.alias}
              width={128}
              height={128}
              placeholder="blur"
              blurDataURL={env.APP_BLUR_DATA_URL}
            />
          </div>
          <div className="card-body align-self-center text-center">
            <h5 className="card-title">
              <Link
                href={userInfo.id ? `/users/${userInfo.id}` : '/login'}
                className="link-body-emphasis link-offset-3 link-underline-opacity-0 link-underline-opacity-100-hover"
              >
                {userInfo.alias}
              </Link>
            </h5>

            <p className="card-text my-3">
              {userInfo.roles
                .filter((item) => !item.hide)
                .map((item) => item.name)
                .join(' / ')}
            </p>
          </div>
        </div>
      </div>
      <div className="col col-lg-10 px-0">
        <div className="card border-0 rounded-0">
          <div className="card-body">
            <textarea
              name="commentContent"
              className="form-control my-2"
              rows={7}
              placeholder={translatedFields.enterReply}
              value={commentContent}
              onChange={onChangeCommentContent}
            ></textarea>
            <button
              disabled={createCommentMutation.isLoading || !commentContent}
              onClick={onClickPostComment}
              type="button"
              className="btn btn-outline-primary my-3 w-100"
            >
              {createCommentMutation.isLoading ? (
                <Spinner classs="me-2" />
              ) : (
                <i className="bi bi-cursor me-2"></i>
              )}
              {translatedFields.postReply}
            </button>
          </div>
        </div>
      </div>
    </div>
  );
}
